package com.ptu.spzx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ptu.spzx.common.exception.ptuException;
import com.ptu.spzx.domain.Class.Classes;
import com.ptu.spzx.domain.Class.ClassesCourse;
import com.ptu.spzx.domain.Class.dto.ClassPageDto;
import com.ptu.spzx.domain.Class.dto.ClassesDTO;
import com.ptu.spzx.domain.Class.vo.ClassVo;
import com.ptu.spzx.domain.Delete.DeleteIds;
import com.ptu.spzx.domain.Question.po.Question;
import com.ptu.spzx.mapper.ClassesCourseMapper;
import com.ptu.spzx.mapper.ClassesMapper;
import com.ptu.spzx.mapper.ExamClassMapper;
import com.ptu.spzx.service.IClassesService;
import com.ptu.spzx.feign.userInfo.UserInfoFeignClient;
import com.ptu.spzx.model.entity.user.UserInfo;
import com.ptu.spzx.model.vo.common.ResultCodeEnum;
import com.ptu.spzx.utils.BeanCopyUtils;
import jakarta.validation.constraints.Max;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author YT
 * @since 2024-01-28
 */
@Service
@Slf4j
public class ClassesServiceImpl extends ServiceImpl<ClassesMapper, Classes> implements IClassesService {

    @Autowired
    ClassesMapper classesMapper;
    @Autowired
    ClassesCourseMapper classesCourseMapper;
    @Autowired
    ClassesCourseServiceImpl classesCourseService;
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;
    @Autowired
    private ExamClassMapper examClassMapper;

    @Override
    @Transactional
    public void addClass(ClassesDTO classesDTO) {
        String name = classesDTO.getName();
        Classes classesName = classesMapper.selectByName(name);
        List<String> stuIds = classesDTO.getStuIds();
            //判断学生是否存在班级
            if(stuIds!=null&&stuIds.size()!=0){
                for (String stuId:stuIds){
                    UserInfo stu = userInfoFeignClient.getStu(stuId);
                    if(stu==null){
                        throw new ptuException(ResultCodeEnum.DATA_EXIST);
                    }
                }
            }
        if (classesName != null) {
            throw new ptuException(ResultCodeEnum.DATA_EXIST);
        }
        Classes classes = BeanCopyUtils.copyBean(classesDTO, Classes.class);
        classesMapper.insert(classes);
        for (Long courseId : classesDTO.getCourseIds()) {
            ClassesCourse classesCourse = new ClassesCourse();
            classesCourse.setClassesId(classes.getId());
            classesCourse.setBelongCourseId(courseId);
            classesCourseMapper.insert(classesCourse);
        }
        if(stuIds!=null&&stuIds.size()!=0){
            userInfoFeignClient.setClassId(stuIds, name);
        }
    }

    @Override
    public PageInfo<Classes> findByPage(Integer pageNum, Integer pageSize, ClassPageDto classPageDto) {
        LambdaQueryWrapper<Classes> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        if(classPageDto.getKeyword()!=null||classPageDto.getKeyword()!=" "){
            lambdaQueryWrapper.like(Classes::getName,classPageDto.getKeyword());
        }
        lambdaQueryWrapper.orderByAsc(Classes::getId);
        PageHelper.startPage(pageNum,pageSize);
        List<Classes> classes = classesMapper.selectList(lambdaQueryWrapper);
        PageInfo<Classes> pageInfo = new PageInfo<>(classes);
        return pageInfo;
    }

    @Override
    public PageInfo<UserInfo> findAllStuByClass(List<Long> classIds, Integer pageNum, Integer pageSize) {
        if(classIds==null){
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        List<String> className=new ArrayList<>();
        for(Long classId:classIds){
            Classes classes = classesMapper.selectById(classId);
            String name = classes.getName();
            className.add(name);
        }
        PageInfo<UserInfo> stuListByClassName = userInfoFeignClient.getStuListByClassName(className, pageNum, pageSize);
        return stuListByClassName;
    }

    @Override
    public PageInfo<UserInfo> findAllStuByCourse(List<Long> courseIds, Integer pageNum, Integer pageSize) {
        if(courseIds==null){
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        List<Long> AllClassId=new ArrayList<>();
        for(Long courseId:courseIds){
            List<Long> classIds=classesCourseMapper.selectClassIdByCourseId(courseId);
            if(classIds==null){
                throw new ptuException(ResultCodeEnum.DATA_ERROR);
            }
            AllClassId.addAll(classIds);
        }
        List<String> className=new ArrayList<>();
        for(Long classId:AllClassId){
            Classes classes = classesMapper.selectById(classId);
            String name = classes.getName();
            className.add(name);
        }
        PageInfo<UserInfo> stuListByClassName = userInfoFeignClient.getStuListByClassName(className, pageNum, pageSize);
        return stuListByClassName;
    }

    @Override
    public PageInfo<UserInfo> findAllStuByExam(Long examId, Integer pageNum, Integer pageSize) {
        if(examId==null){
            throw new ptuException(ResultCodeEnum.PARAM_NULL);
        }
        List<Long> classIds=examClassMapper.selectByExamId(examId);
        List<String> className=new ArrayList<>();
        for(Long classId:classIds){
            Classes classes = classesMapper.selectById(classId);
            String name = classes.getName();
            className.add(name);
        }
        PageInfo<UserInfo> stuListByClassName = userInfoFeignClient.getStuListByClassName(className, pageNum, pageSize);
        return stuListByClassName;
    }

    @Override
    public PageInfo<Classes> getClassByCourseId(Long courseId, Integer pageNum, Integer pageSize) {
        List<Long> classIds = classesCourseMapper.selectClassIdByCourseId(courseId);
        LambdaQueryWrapper<Classes> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(Classes::getId,classIds);
        PageHelper.startPage(pageNum,pageSize);
        List<Classes> classes = classesMapper.selectList(lambdaQueryWrapper);
        PageInfo<Classes> classesPageInfo=new PageInfo<>(classes);
        return classesPageInfo;
    }

    @Override
    @Transactional
    public void updateClass(ClassesDTO classesDTO) {
        if(classesDTO.getId()==null){
            throw new ptuException(ResultCodeEnum.DATA_NOT_EXIST);
        }
        Classes orignClasses = classesMapper.selectById(classesDTO.getId());
        if(orignClasses==null){
            throw new ptuException(ResultCodeEnum.DATA_NOT_EXIST);
        }
        String name = orignClasses.getName();
        userInfoFeignClient.setClassNull(name);
        Classes classes = BeanCopyUtils.copyBean(classesDTO, Classes.class);
        classesMapper.updateById(classes);
        classesCourseMapper.deleteByClassId(classesDTO.getId());
        if(classesDTO.getCourseIds()!=null){
            for(Long courseId:classesDTO.getCourseIds()){
                ClassesCourse classesCourse = new ClassesCourse();
                classesCourse.setClassesId(classes.getId());
                classesCourse.setBelongCourseId(courseId);
                classesCourseMapper.insert(classesCourse);
            }
        }
        if(classesDTO.getStuIds()!=null){
            List<String> stuIds = classesDTO.getStuIds();
            userInfoFeignClient.setClassId(stuIds, classes.getName());
        }
    }


    /**
     * 删除班级，同时删除班级课程关系
     *
     * @param
     * @return
     */
    @Override
    @Transactional //如果失败，回滚事务
    public void deleteBatchClassByIds(DeleteIds deleteIds) {
        List<Long> ids = deleteIds.getIds();
        if (ids.isEmpty()) {
            throw new ptuException(ResultCodeEnum.DATA_ERROR);
        }
        for(long id:ids){
            Classes classes = classesMapper.selectById(id);
            if(classes==null){
                throw new ptuException(ResultCodeEnum.DATA_NOT_EXIST);
            }
            String name = classes.getName();
            userInfoFeignClient.setClassNull(name);
        }
        classesCourseMapper.delete(new QueryWrapper<ClassesCourse>().in("classes_id", ids));
        classesMapper.deleteBatchIds(ids);
    }

}
